﻿using AutoMapper;
using Dapper;
using Hangfire;
using housingsafety.server.Caching.Core;
using housingsafety.server.Entities;
using housingsafety.server.Entities.DataModels;
using housingsafety.server.Helpers;
using housingsafety.server.Models;
using housingsafety.server.Repository;
using housingsafety.server.Repository.Extensions;
using housingsafety.server.Svcs;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Npgsql;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace housingsafety.server.Controllers
{
    /// <summary>
    /// 楼栋阳台管理服务
    /// </summary>
    public class BuildMngController : BaseController<BuildMngController>
    {
        private readonly IRepository<ZmVillageFireSafety> _villageFireSafetyRepository;
        private readonly ICache _cache;
        private readonly IMapper _mapper;
        private readonly IStorageProvider _storageProvider;
        private readonly ZmDbContext _dbContext;
        private readonly IRepository<ZmUser> _userRepository;
        private readonly IRepository<ZmBuildings> _buildingsRepository;
        private readonly IRepository<ZmBuildingsLayer> _buildingsLayerRepository;
        private readonly IRepository<ZmFileAttach> _fileAttachRepository;
        private readonly IRepository<ZmPlaceCommercial> _placeCommercialRepository;
        private readonly IRepository<ZmPlaceResident> _placeResidentRepository;
        private readonly IOptions<StaticDataConf> _staticVtOptions;
        private readonly IRepository<ZmDepartment> _departmentRepository;
        private readonly IRepository<RiskCensusHouseYhpc> _riskHouseRepository;
        private readonly IRepository<RiskCensusYhpcUpldFile> _riskHouseFileRepository;
        private readonly IRepository<ZmPlaceResidentCheck> _placeResidentCheckRepository;
        private readonly IRepository<ZmPlaceCommercialCheck> _placeCommercialCheckRepository;

        private readonly Microsoft.AspNetCore.Http.Features.FormOptions _defaultFormOptions = new Microsoft.AspNetCore.Http.Features.FormOptions();
        private readonly string[] _permittedExtensions = { ".mp3", ".mp4", ".jpg", ".jpeg", ".png", ".geojson", ".doc", ".docx" };

        private static object _lock = new object();

        public BuildMngController(IStorageProvider storageProvider
            , IRepository<ZmDepartment> departmentRepository
            , IRepository<ZmUser> userRepository
              , IRepository<ZmVillageFireSafety> villageFireSafetyRepository
            //, IRepository<ZmBuildings> buildingsRepository
            , IRepository<ZmBuildingsLayer> buildingsLayerRepository
            , IRepository<ZmFileAttach> fileAttachRepository
            , IRepository<ZmPlaceCommercial> placeCommercialRepository
            , IRepository<ZmPlaceResident> placeResidentRepository
            , IRepository<RiskCensusHouseYhpc> riskHouseRepository
            , IRepository<RiskCensusYhpcUpldFile> riskHouseFileRepository
            , IRepository<ZmPlaceResidentCheck> placeResidentCheckRepository
            , IRepository<ZmPlaceCommercialCheck> placeCommercialCheckRepository
            , IMapper mapper, ICacheProvider cacheProvider, ZmDbContext dbContext
            , IOptions<StaticDataConf> staticVtOptions
            , ILogger<BuildMngController> logger
            , IRepository<ZmSystemLog> systemLogRepository) : base(logger, systemLogRepository)
        {
            _storageProvider = storageProvider;
            _mapper = mapper;
            _dbContext = dbContext;
            _cache = cacheProvider.CreateCache();

            _userRepository = userRepository;
            //_buildingsRepository = buildingsRepository;
            _buildingsLayerRepository = buildingsLayerRepository;
            _fileAttachRepository = fileAttachRepository;
            _placeCommercialRepository = placeCommercialRepository;
            _placeResidentRepository = placeResidentRepository;
            _staticVtOptions = staticVtOptions;
            _departmentRepository = departmentRepository;
            _riskHouseRepository = riskHouseRepository;
            _riskHouseFileRepository = riskHouseFileRepository;
            _placeResidentCheckRepository = placeResidentCheckRepository;
            _placeCommercialCheckRepository = placeCommercialCheckRepository;
            _villageFireSafetyRepository = villageFireSafetyRepository;
        }



        /// <summary>
        /// 获取房屋信息_yhpc
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("build/{id}/info")]
        [Produces("application/json")]
        [ProducesResponseType(typeof(RespRet<RiskCensusHouseYhpc>), 200)]
        public RespRet<RiskCensusHouseYhpc> houses_yhpc([FromRoute] string id)
        {
            if (string.IsNullOrEmpty(id))
            {
                return new RespRet<RiskCensusHouseYhpc>(false, "id can not be null");
            }

            var userNumber = this.CurrentUser();
            if (string.IsNullOrEmpty(userNumber))
            {
                return new RespRet<RiskCensusHouseYhpc>(false, "user not logined");
            }

            var sbSql = new StringBuilder();
            var sqlParams = new List<NpgsqlParameter>();
            sbSql.Append($@"select *  from zm_yt_build 
                where build_no=@id");
            sqlParams.Add(new NpgsqlParameter("id", id));

            var data = _dbContext.RiskCensusHouseYhpc.FromSqlRaw(sbSql.ToString(), sqlParams.ToArray())
                .FirstOrDefault();
            if (null == data)
            {
                return new RespRet<RiskCensusHouseYhpc>(false, "未查询到楼栋信息");
            }

            var dataDto = _mapper.Map<RiskCensusHouseYhpc>(data);

            return new RespRet<RiskCensusHouseYhpc>(true, "Ok", dataDto);
        }


        /// <summary>
        /// 获取房屋信息_yhpc_photo
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("build_photo/{id}/info")]
        [Produces("application/json")]
        [ProducesResponseType(typeof(RespRet<List<RiskCensusYhpcUpldFile>>), 200)]
        public RespRet<List<RiskCensusYhpcUpldFile>> houses_yhpc_photo([FromRoute] string id)
        {
            if (string.IsNullOrEmpty(id))
            {
                return new RespRet<List<RiskCensusYhpcUpldFile>>(false, "id can not be null");
            }

            var userNumber = this.CurrentUser();
            if (string.IsNullOrEmpty(userNumber))
            {
                return new RespRet<List<RiskCensusYhpcUpldFile>>(false, "user not logined");
            }

            var sbSql = new StringBuilder();
            var sqlParams = new List<NpgsqlParameter>();
            sbSql.Append($@"select * from risk_census_yhpc_upld_file  where group_id=(select photo from risk_census_house_yhpc  where bh='" + id + "')");
            //sqlParams.Add(new NpgsqlParameter("id", id));

            var data = _dbContext.RiskCensusYhpcUpldFileTest.FromSqlRaw(sbSql.ToString()).ToList();

            if (null == data)
            {
                return new RespRet<List<RiskCensusYhpcUpldFile>>(false, "未查询到房屋信息");
            }

            var dataDto = _mapper.Map<List<RiskCensusYhpcUpldFile>>(data);

            return new RespRet<List<RiskCensusYhpcUpldFile>>(true, "Ok", dataDto);
        }


        /// <summary>
        /// 动态矢量瓦片服务(支持编辑)
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="z"></param>
        /// <returns></returns>
        [HttpGet("build/dynamic/vector/tiles")]
        public ActionResult GetIntelLayerVt([FromQuery] int x, [FromQuery] int y, [FromQuery] int z)
        {
            var userNumber = this.CurrentUser();
            if (string.IsNullOrEmpty(userNumber))
            {
                return BadRequest("user not login");
            }

            var tile = GetDynamicVectorTile(z, x, y);
            return File(tile, "application/vnd.mapbox-vector-tile");
        }
        private byte[] GetDynamicVectorTile(int z, int x, int y)
        {
            var sql = @$"SELECT 
ST_AsMVT(P, 'ffpolygon', 4096, 'geom') AS tile 
FROM 
(SELECT 
ST_AsMVTGeom( ST_Transform(ST_SetSRID(geom, 4326), 3857), ST_TileEnvelope( {z}, {x}, {y}),4096,256,FALSE) AS geom, 
id,fwbh,yhfwbh,address,pczt_housing as pcztHousing,pczt_fire as pcztFire,pczt_police as pcztPolice 
FROM zm_buildings 
WHERE ST_Intersects(ST_SetSRID(geom, 4326), ST_Transform(ST_TileEnvelope( {z}, {x}, {y}), 4326))) AS P";
            var tile = _dbContext.Database.GetDbConnection().Query<byte[]>(sql).FirstOrDefault();
            return tile;
        }
    }
}
